#!/usr/bin/env node

// @ts-nocheck
const glob = require('glob');
const JestWorker = require('jest-worker').Worker || require('jest-worker').default;
const chalk = require('chalk');
const path = require('path');
const ora = require('ora');

/**
 *
 * @param {string} workerPath 绝对路径
 * @param {object} opt 选项
 * @param {string} opt.globPattern 选项
 * @param {(result) => void} opt.onResult 选项
 */
exports.workerRun = function workerRun(workerPath, opt) {
  return worker(workerPath, opt).catch((err) => {
    console.trace(err);
    process.exitCode = 0;
  });
};

/**
 *
 * @param {string} workerPath 绝对路径
 * @param {object} opt 选项
 */
async function worker(workerPath, opt = {globPattern: 'src/**/*.{ts,tsx,js,scss}'}) {
  let files = glob.sync(opt.globPattern, { cwd: process.cwd(), absolute: true });
  files = files.filter(f => /\.d\.ts$/m.test(f) === false);
  const startTime = new Date().getTime();
  const numWorkers = opt && opt.numWorkers ? opt.numWorkers : Math.min(Math.max(files.length, 1), 4);
  const worker = createJestWorker(workerPath, { numWorkers });

  // 透传参数只能是纯对象，不能包含function
  const wokerOpt = {}
  Object.entries(opt).forEach(([k,v]) => (typeof v !== 'function') && (wokerOpt[k] = v)  )
  
  console.log(' 任务参数:', wokerOpt)
  
  const spinner = ora(`${chalk.green('任务执行中')}`).start();
  // run command
  const result = await Promise.all(files.map((file) => worker.transform(file, wokerOpt)));
  spinner.succeed('任务执行成功');

  opt && opt.onResult && await opt.onResult(result);

  await worker.end();

  const eatTime = (new Date().getTime() - startTime) / 1000;
  console.log(chalk.green(`耗时 ${chalk.yellow(eatTime)} 秒`));
}

function createJestWorker(workerPath, { numWorkers = 4 }) {
  const worker = new JestWorker(workerPath, {
    exposedMethods: ['transform'],
    numWorkers,
    enableWorkerThreads: true,
  });

  worker.getStdout().pipe(process.stdout);
  worker.getStderr().pipe(process.stderr);
  return worker;
}
